/*
 * 项目名称:    wms-server-jeecg
 * 创建人员:    FanZhiwen
 * 创建时间:    2023-10-17
 */
package org.jeecg.modules.flow.callback.inbound.order;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.basic.material.entity.BasicMaterial;
import org.jeecg.modules.basic.material.mapper.BasicMaterialMapper;
import org.jeecg.modules.basic.material.service.IBasicMaterialService;
import org.jeecg.modules.basic.print.entity.PrintConfig;
import org.jeecg.modules.basic.print.service.IPrintConfigService;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouse;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseArea;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseAreaLocation;
import org.jeecg.modules.basic.warehouse.mapper.WmsBasicWarehouseMapper;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaLocationService;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaService;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseService;
import org.jeecg.modules.business.doc.business.entity.WmsInReceipt;
import org.jeecg.modules.business.doc.business.entity.WmsInReceiptMaterial;
import org.jeecg.modules.business.doc.business.mapper.WmsInReceiptMapper;
import org.jeecg.modules.business.doc.business.mapper.WmsInReceiptMaterialMapper;
import org.jeecg.modules.business.doc.business.service.IWmsInReceiptMaterialService;
import org.jeecg.modules.business.repertory.entity.WmsRepertory;
import org.jeecg.modules.business.repertory.service.IWmsRepertoryService;
import org.jeecg.modules.business.third.service.IMesStatusService;
import org.jeecg.modules.business.warehouse.entity.InspectResultEnum;
import org.jeecg.modules.business.warehouse.entity.InspectStatusEnum;
import org.jeecg.modules.business.warehouse.entity.WmsInReceiptTask;
import org.jeecg.modules.business.warehouse.entity.WmsInReceiptTaskMaterial;
import org.jeecg.modules.business.warehouse.service.IWmsInReceiptTaskMaterialService;
import org.jeecg.modules.business.warehouse.service.IWmsInReceiptTaskService;
import org.jeecg.modules.flow.callback.enums.DocumentStatusEnum;
import org.jeecg.modules.flow.callback.enums.InboundStatusEnum;
import org.jeecg.modules.flow.callback.inbound.mapper.MaterialInfoVO;
import org.jeecg.modules.flow.callback.inbound.mapper.WmsValidMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 入库业务通用工具
 *
 * @author FanZhiwen
 * @version 1.0.0
 * @since 2023-10-17
 */
@Component
@Slf4j
public class InBoundBeanUtils {
    @Autowired
    private IWmsInReceiptMaterialService wmsInReceiptMaterialService;
    @Autowired
    private IWmsRepertoryService wmsRepertoryService;
    @Resource
    private WmsValidMapper wmsValidMapper;
    @Autowired
    private IWmsBasicWarehouseService warehouseService;
    @Autowired
    private IWmsBasicWarehouseAreaService wmsBasicWarehouseAreaService;
    @Autowired
    private IWmsBasicWarehouseAreaLocationService wmsBasicWarehouseAreaLocationService;
    @Resource
    private BasicMaterialMapper basicMaterialMapper;
    @Resource
    private WmsBasicWarehouseMapper wmsBasicWarehouseMapper;
    @Resource
    private WmsInReceiptMapper wmsInReceiptMapper;
    @Autowired
    private IWmsInReceiptTaskMaterialService iWmsInReceiptTaskMaterialService;
    @Autowired
    private IWmsInReceiptTaskService iWmsInReceiptTaskService;
    @Resource
    private WmsInReceiptMaterialMapper wmsInReceiptMaterialMapper;
    @Autowired
    private IMesStatusService iMesStatusService;
    @Autowired
    private IPrintConfigService iPrintConfigService;
    @Autowired
    private IBasicMaterialService basicMaterialService;
    private String[] documentTypes = {"R03", "R05", "R07", "R09", "R16", "R23", "R26", "R31", "R35", "R62"};

    /**
     * 整个任务结束通知MES任务完成
     *
     * @param taskId
     * @return void
     * @author FanZhiwen
     * @since 2023/10/16 10:08
     */
    public void sendMesCompleted(String taskId) {
        WmsInReceiptTask task = iWmsInReceiptTaskService.getById(taskId);
        if (ObjectUtil.isNotNull(task)) {
            if (ArrayUtil.contains(documentTypes, task.getDocumentType())) {
                log.info("通知mes任务结束,任务ID: {}", taskId);
                try {
                    iMesStatusService.warehouse(taskId, null, 2, null);
                } catch (Exception e) {
                    log.info("通知mes任务结束异常:", e);
                }
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateTaskWareHouseStatus(String taskId) {
        WmsInReceiptTask task = iWmsInReceiptTaskService.getById(taskId);
        List<WmsInReceiptTaskMaterial> materialList = iWmsInReceiptTaskMaterialService.list(new LambdaQueryWrapper<WmsInReceiptTaskMaterial>()
                .eq(WmsInReceiptTaskMaterial::getWmsInReceiptTaskId, taskId)
        );
        //任务总数量
        BigDecimal total = materialList.stream().filter(s -> ObjectUtil.isNotNull(s.getPlanQuantity())).map(WmsInReceiptTaskMaterial::getPlanQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        //任务下的所有已入库的入库单
        List<WmsInReceipt> inReceipts = wmsInReceiptMapper.selectList(new LambdaQueryWrapper<WmsInReceipt>()
                .eq(WmsInReceipt::getWmsInReceiptTaskId, taskId)
                .eq(WmsInReceipt::getDocumentStatus, DocumentStatusEnum.COMPLETE.getCode())
        );
        List<WmsInReceiptMaterial> inReceiptMaterials = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(inReceipts)) {
            inReceiptMaterials = wmsInReceiptMaterialMapper.selectList(new LambdaQueryWrapper<WmsInReceiptMaterial>()
                    .in(WmsInReceiptMaterial::getWmsInReceiptId, inReceipts.stream().map(WmsInReceipt::getId).collect(Collectors.toList()))
            );
        }
        BigDecimal decimal = inReceiptMaterials.stream().filter(s -> ObjectUtil.isNotNull(s.getWarehouseQuantity())).map(WmsInReceiptMaterial::getWarehouseQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (total.compareTo(decimal) <= 0) {
            task.setWarehouseStatus(InboundStatusEnum.ALL.getCode());
            task.setDocumentStatus(DocumentStatusEnum.COMPLETE.getCode());
        }
        if (total.compareTo(decimal) > 0) {
            task.setWarehouseStatus(InboundStatusEnum.PART.getCode());
            task.setDocumentStatus(DocumentStatusEnum.PROCESS.getCode());
        }
        iWmsInReceiptTaskService.updateById(task);
    }

    public Map<String, List<String>> valid(String wmsInReceiptId) {
        WmsInReceipt wmsInReceipt = wmsInReceiptMapper.selectById(wmsInReceiptId);
        List<WmsInReceiptMaterial> inReceiptMaterials = wmsInReceiptMaterialService.list(new LambdaQueryWrapper<WmsInReceiptMaterial>()
                .eq(WmsInReceiptMaterial::getWmsInReceiptId, wmsInReceiptId)
        );
        Map<String, List<String>> res = new HashMap<>();
        List<String> warnList = new ArrayList<>();
        List<String> stopList = new ArrayList<>();
        //校验批次号
        Map<String, List<String>> validByBatchMap = validBatchCode(inReceiptMaterials);
        //校验库存
        Map<String, List<String>> validByStockMap = validWareHouse(inReceiptMaterials);
        //校验仓库物料类型
        List<String> validByMaterialType = validMaterialTypeByHouse(inReceiptMaterials);
        //校验是否超额入库
        boolean validBeyondInNumber = validBeyondInNumber(wmsInReceipt,inReceiptMaterials);
        //校验是否可分批出入库,该校验在点击确认后,需要进行业务操作
        List<String> printConfigCanBatch = validPrintConfig(wmsInReceipt,inReceiptMaterials);
        //校验仓库合法性
        validWarehouseIdExsit(inReceiptMaterials);
        //校验检验合格
        validInspect(wmsInReceipt,inReceiptMaterials);
        //校验是否选到了精确位置
        validLocation(inReceiptMaterials);
        //校验一个任务已经存在提交后入库单，又重新提交入库单时，需要去校验之前入库单的物料信息是否和本次提交的入库单物料信息存在冲突，如果有冲突要提示报错
        validSubmit(wmsInReceipt,inReceiptMaterials);
        if (validBeyondInNumber) {
            warnList.add("入库数量超入库任务,是否确认入库?");
        }
        if (CollectionUtil.isNotEmpty(validByBatchMap.get("2"))) {
            warnList.addAll(validByBatchMap.get("2"));
        }
        if (CollectionUtil.isNotEmpty(validByBatchMap.get("3"))) {
            stopList.addAll(validByBatchMap.get("3"));
        }
        if (CollectionUtil.isNotEmpty(validByStockMap.get("2"))) {
            warnList.addAll(validByStockMap.get("2"));
        }
        if (CollectionUtil.isNotEmpty(validByStockMap.get("3"))) {
            stopList.addAll(validByStockMap.get("3"));
        }
        if (CollectionUtil.isNotEmpty(validByMaterialType)) {
            warnList.addAll(validByMaterialType);
        }
        if (CollectionUtil.isNotEmpty(printConfigCanBatch)) {
            warnList.addAll(printConfigCanBatch);
        }
        //2是需要做警告的
        res.put("2", warnList);
        //3是禁止入库的
        res.put("3", stopList);
        //需要进行业务操作的
        res.put("printConfigCanBatch", printConfigCanBatch);
        for (String s : res.keySet()) {
            List<String> list = res.get(s);
            if (CollectionUtil.isNotEmpty(list)) {
                res.replace(s, list.stream().distinct().collect(Collectors.toList()));
            }
        }
        return res;

    }

    /**
     * 校验批次号
     * 物料分类增加“同批次号入库控制方式”,如果入库的批次号和库存中已有的批次号相同,则校验
     *
     * @return void
     * @author FanZhiwen
     * @since 2023/10/17 17:51
     */
    public Map<String, List<String>> validBatchCode(List<WmsInReceiptMaterial> inReceiptMaterialList) {
        Map<String, List<String>> map = new HashMap<>();
        List<String> warnList = new ArrayList<>();
        List<String> stopList = new ArrayList<>();
        inReceiptMaterialList = inReceiptMaterialList.stream().filter(s -> StrUtil.isNotBlank(s.getBatchCode())).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(inReceiptMaterialList)) {
            //入库单下的物料id集合
            List<String> materialIdList = inReceiptMaterialList.stream().map(WmsInReceiptMaterial::getWmsBasicMaterialId).collect(Collectors.toList());
            List<MaterialInfoVO> infoVOS = wmsValidMapper.selectInboundControlType(materialIdList);
            //物料id-控制方式map
            Map<String, String> collect = infoVOS.stream().filter(s -> ObjectUtil.isNotNull(s.getInboundControlType())).collect(Collectors.toMap(MaterialInfoVO::getWmsBasicMaterialId, MaterialInfoVO::getInboundControlType));
            //物料id-物料名称map
            Map<String, String> materialNameMap = infoVOS.stream().collect(Collectors.toMap(MaterialInfoVO::getWmsBasicMaterialId, MaterialInfoVO::getMaterialName));
            //批次号集合
            List<String> batchList = inReceiptMaterialList.stream().filter(s -> ObjectUtil.isNotNull(s.getBatchCode())).map(WmsInReceiptMaterial::getBatchCode).collect(Collectors.toList());
            List<WmsRepertory> batchMaterialList = wmsRepertoryService.list(new LambdaQueryWrapper<WmsRepertory>()
                    .in(WmsRepertory::getBatchCode, batchList)
            );
            //仓库id-仓库map
            Map<String, String> warehouseIdMap = wmsBasicWarehouseMapper.selectList(new LambdaQueryWrapper<>()).stream().collect(Collectors.toMap(s -> s.getId(), s -> s.getName()));
            //查询物料id对应的库存
            inReceiptMaterialList.forEach(one -> {
                if (CollectionUtil.isNotEmpty(batchMaterialList)) {
                    List<WmsRepertory> list = batchMaterialList.stream().filter(s -> s.getBatchCode().equals(one.getBatchCode())).collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(list)) {
                        //做警告
                        if ("2".equals(collect.get(one.getWmsBasicMaterialId()))) {
//                            warnList.add("物料:" + materialNameMap.get(one.getWmsBasicMaterialId()) + "批次号:" + one.getBatchCode() + "已存在该批次号,是否确认入库?");
                            warnList.add("当前仓库:"+warehouseIdMap.get(one.getWmsBasicWarehouseId())+"下已存在批次号为"+one.getBatchCode()+"的"+materialNameMap.get(one.getWmsBasicMaterialId())+"物料,是否入库?");
                            //禁止入库
                        } else if ("3".equals(collect.get(one.getWmsBasicMaterialId()))) {
                            //（改为不拦截）
//                            stopList.add("物料:" + materialNameMap.get(one.getWmsBasicMaterialId()) + "批次号:" + one.getBatchCode() + "已存在该批次号,不可入库!");
//                            stopList.add("当前仓库:"+warehouseIdMap.get(one.getWmsBasicWarehouseId())+"下已存在批次号为"+one.getBatchCode()+"的"+materialNameMap.get(one.getWmsBasicMaterialId())+"物料,同批次号禁止入库!");
                        }
                    }
                }
            });
            map.put("2", warnList);
            map.put("3", stopList);
        }
        return map;
    }

    /**
     * 根据仓库超容量控制方式,超过容量（宽度和库存数量）入库校验
     * 最大容量控制增加主单位、辅单位不同选项的控制:原料采购、调拨入库时,
     * SAP传入的库存单位为KG，WMS系统启用辅单位,辅单位为PCS,数量默认为1,库存容量控制按照辅助单位控制
     *
     * @return void
     * @author FanZhiwen
     * @since 2023/10/17 18:45
     */
    public Map<String, List<String>> validWareHouse(List<WmsInReceiptMaterial> inReceiptMaterialList) {
        Map<String, List<String>> res = new HashMap<>();
        //获取所有仓库id
        List<String> houseIdList = inReceiptMaterialList.stream().map(WmsInReceiptMaterial::getWmsBasicWarehouseId).distinct().collect(Collectors.toList());
        //获取仓库实体
        List<WmsBasicWarehouse> houseList = warehouseService.list(new LambdaQueryWrapper<WmsBasicWarehouse>()
                .in(CollectionUtil.isNotEmpty(houseIdList), WmsBasicWarehouse::getId, houseIdList)
        );
        //获取所有库区id
        List<String> areaIdList = inReceiptMaterialList.stream().filter(s -> ObjectUtil.isNotNull(s.getWmsBasicWarehouseAreaId())).map(WmsInReceiptMaterial::getWmsBasicWarehouseAreaId).distinct().collect(Collectors.toList());
        //获取库区实体
        List<WmsBasicWarehouseArea> areaList = wmsBasicWarehouseAreaService.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .in(CollectionUtil.isNotEmpty(areaIdList), WmsBasicWarehouseArea::getId, areaIdList)
        );
        //获取所有库位id
        List<String> storeLocationIdList = inReceiptMaterialList.stream().filter(s -> ObjectUtil.isNotNull(s.getWmsBasicWarehouseAreaLocationId())).map(WmsInReceiptMaterial::getWmsBasicWarehouseAreaLocationId).distinct().collect(Collectors.toList());
        //获取库位实体
        List<WmsBasicWarehouseAreaLocation> storeLocationList = wmsBasicWarehouseAreaLocationService.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                .in(CollectionUtil.isNotEmpty(storeLocationIdList), WmsBasicWarehouseAreaLocation::getId, storeLocationIdList)
        );
        //获取仓库id-仓库实体map
        Map<String, WmsBasicWarehouse> houseMap = houseList.stream().collect(Collectors.toMap(s -> s.getId(), s -> s));
        //获取库区id-库区实体map
        Map<String, WmsBasicWarehouseArea> areaMap = areaList.stream().collect(Collectors.toMap(s -> s.getId(), s -> s));
        //获取库位id-库位实体map
        Map<String, WmsBasicWarehouseAreaLocation> storeLocationMap = storeLocationList.stream().collect(Collectors.toMap(s -> s.getId(), s -> s));
        //只精确到仓库的(库区库位为空)
        List<WmsInReceiptMaterial> inReceiptHouseList = inReceiptMaterialList.stream().filter(s -> StrUtil.isBlank(s.getWmsBasicWarehouseAreaId()) && StrUtil.isBlank(s.getWmsBasicWarehouseAreaLocationId())).collect(Collectors.toList());
        //精确到库区的(库区不为空,库位为空)
        List<WmsInReceiptMaterial> inReceiptAreaList = inReceiptMaterialList.stream().filter(s -> StrUtil.isNotBlank(s.getWmsBasicWarehouseAreaId()) && StrUtil.isBlank(s.getWmsBasicWarehouseAreaLocationId())).collect(Collectors.toList());
        //精确到库位的(库区和库位都不为空)
        List<WmsInReceiptMaterial> inReceiptStoreLocationList = inReceiptMaterialList.stream().filter(s -> StrUtil.isNotBlank(s.getWmsBasicWarehouseAreaId()) && StrUtil.isNotBlank(s.getWmsBasicWarehouseAreaLocationId())).collect(Collectors.toList());
        Map<Integer, List<WmsInReceiptMaterial>> map = new HashMap<>();
        map.put(1, inReceiptHouseList);
        map.put(2, inReceiptAreaList);
        map.put(3, inReceiptStoreLocationList);
        Arrays.asList(1, 2, 3).forEach(one -> {
            //精确级别分类list
            List<WmsInReceiptMaterial> list = map.get(one);
            if (CollectionUtil.isNotEmpty(list)) {
                Map<String, List<WmsInReceiptMaterial>> collectHouse = list.stream().collect(Collectors.groupingBy(s -> s.getWmsBasicWarehouseId() + "-" + s.getWmsBasicWarehouseAreaId() + "-" + s.getWmsBasicWarehouseAreaLocationId()));
                collectHouse.keySet().forEach(joinKey -> {
                    List<WmsInReceiptMaterial> materialList = collectHouse.get(joinKey);
                    if (CollectionUtil.isNotEmpty(materialList)) {
                        //获取仓库实体
                        WmsBasicWarehouse wmsBasicWarehouse = houseMap.get(StrUtil.split(joinKey, "-")[0]);
                        if (ObjectUtil.isNotNull(wmsBasicWarehouse)) {
                            WmsBasicWarehouseArea wmsBasicWarehouseArea = areaMap.get(StrUtil.split(joinKey, "-")[1]);
                            WmsBasicWarehouseAreaLocation wmsBasicWarehouseAreaLocation = storeLocationMap.get(StrUtil.split(joinKey, "-")[2]);
                            if (StrUtil.isNotBlank(wmsBasicWarehouse.getCapacityControlUnit())) {
                                //按库存单位校验
                                if ("1".equals(wmsBasicWarehouse.getCapacityControlUnit())) {
                                    Map<String, List<String>> mapByOneWay = validByStockUnit(collectHouse.get(joinKey), wmsBasicWarehouse, wmsBasicWarehouseArea, wmsBasicWarehouseAreaLocation);
                                    mapByOneWay.keySet().forEach(key -> {
                                        if (CollectionUtil.isNotEmpty(mapByOneWay.get(key))) {
                                            if (CollectionUtil.isEmpty(res.get(key))) {
                                                res.put(key, mapByOneWay.get(key));
                                            } else {
                                                List<String> sumResList = res.get(key);
                                                sumResList.addAll(mapByOneWay.get(key));
                                                res.replace(key, sumResList);
                                            }
                                        }
                                    });
                                }
                                //按辅助单位校验
                                if ("2".equals(wmsBasicWarehouse.getCapacityControlUnit())) {
                                    Map<String, List<String>> mapByOneWay = validByAssistantUnit(collectHouse.get(joinKey), wmsBasicWarehouse, wmsBasicWarehouseArea, wmsBasicWarehouseAreaLocation);
                                    mapByOneWay.keySet().forEach(key -> {
                                        if (CollectionUtil.isNotEmpty(mapByOneWay.get(key))) {
                                            if (CollectionUtil.isEmpty(res.get(key))) {
                                                res.put(key, mapByOneWay.get(key));
                                            } else {
                                                List<String> sumResList = res.get(key);
                                                sumResList.addAll(mapByOneWay.get(key));
                                                res.replace(key, sumResList);
                                            }
                                        }
                                    });
                                }
                                //按库存单位和辅助单位校验
                                if ("1,2".equals(wmsBasicWarehouse.getCapacityControlUnit())) {

                                }
                            }
                        }
                    }
                });
            }
        });
        return res;
    }

    /**
     * 根据库存单位校验
     */
    Map<String, List<String>> validByStockUnit(List<WmsInReceiptMaterial> inReceiptMaterialList, WmsBasicWarehouse wmsBasicWarehouse, WmsBasicWarehouseArea wmsBasicWarehouseArea, WmsBasicWarehouseAreaLocation wmsBasicWarehouseAreaLocation) {
        Map<String, List<String>> res = new HashMap<>();
        List<String> warnList = new ArrayList<>();
        List<String> stopList = new ArrayList<>();
        List<WmsRepertory> repertoryList = new ArrayList<>();
        //精确等级标识 1 精确到仓库 2 精确到库区 3 精确到库位
        int levelSign = 0;
        //仓库最大容量 maxCapacity
        BigDecimal maxCapacity = BigDecimal.ZERO;
        //预警容量 warningCapacity
        BigDecimal warningCapacity = BigDecimal.ZERO;
        //只精确到仓库
        if (ObjectUtil.isNull(wmsBasicWarehouseArea) && ObjectUtil.isNull(wmsBasicWarehouseAreaLocation)) {
            //查询此仓库即时库存
            repertoryList = wmsRepertoryService.list(new LambdaQueryWrapper<WmsRepertory>()
                    .eq(WmsRepertory::getWmsBasicWarehouseId, wmsBasicWarehouse.getId())
            );
            if (ObjectUtil.isNotNull(wmsBasicWarehouse.getWarningCapacity())) {
                warningCapacity = wmsBasicWarehouse.getWarningCapacity();
            }
            if (ObjectUtil.isNotNull(wmsBasicWarehouse.getMaxCapacity())) {
                maxCapacity = wmsBasicWarehouse.getMaxCapacity();
            }
            levelSign = 1;
        }
        //只精确到库区
        if (ObjectUtil.isNotNull(wmsBasicWarehouseArea) && ObjectUtil.isNull(wmsBasicWarehouseAreaLocation)) {
            //查询此库区即时库存
            repertoryList = wmsRepertoryService.list(new LambdaQueryWrapper<WmsRepertory>()
                    .eq(WmsRepertory::getWmsBasicWarehouseId, wmsBasicWarehouse.getId())
                    .eq(WmsRepertory::getWmsBasicWarehouseAreaId, wmsBasicWarehouseArea.getId())
            );
            if (ObjectUtil.isNotNull(wmsBasicWarehouseArea.getWarningCapacity())) {
                warningCapacity = wmsBasicWarehouseArea.getWarningCapacity();
            }
            if (ObjectUtil.isNotNull(wmsBasicWarehouseArea.getMaxCapacity())) {
                maxCapacity = wmsBasicWarehouseArea.getMaxCapacity();
            }
            levelSign = 2;
        }
        //只精确到库位
        if (ObjectUtil.isNotNull(wmsBasicWarehouseArea) && ObjectUtil.isNotNull(wmsBasicWarehouseAreaLocation)) {
            //查询此库位即时库存
            repertoryList = wmsRepertoryService.list(new LambdaQueryWrapper<WmsRepertory>()
                    .eq(WmsRepertory::getWmsBasicWarehouseId, wmsBasicWarehouse.getId())
                    .eq(WmsRepertory::getWmsBasicWarehouseAreaId, wmsBasicWarehouseArea.getId())
                    .eq(WmsRepertory::getWmsBasicWarehouseAreaLocationId, wmsBasicWarehouseAreaLocation.getId())
            );
            if (ObjectUtil.isNotNull(wmsBasicWarehouseAreaLocation.getWarningCapacity())) {
                warningCapacity = wmsBasicWarehouseAreaLocation.getWarningCapacity();
            }
            if (ObjectUtil.isNotNull(wmsBasicWarehouseAreaLocation.getMaxCapacity())) {
                maxCapacity = wmsBasicWarehouseAreaLocation.getMaxCapacity();
            }
            levelSign = 3;
        }
        if (ObjectUtil.isNull(warningCapacity)) {
            warningCapacity = BigDecimal.ZERO;
        }
        if (ObjectUtil.isNull(maxCapacity)) {
            maxCapacity = BigDecimal.ZERO;
        }
        //入库单的数量
        BigDecimal inReceiptNumber = inReceiptMaterialList.stream().filter(s -> ObjectUtil.isNotNull(s.getWarehouseQuantity())).map(WmsInReceiptMaterial::getWarehouseQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        //目前已有的即时库存
        BigDecimal totalStock = repertoryList.stream().filter(s -> ObjectUtil.isNotNull(s.getStockQuantity())).map(WmsRepertory::getStockQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        //入库单的数量+目前已有的即时库存
        BigDecimal addNumber = inReceiptNumber.add(totalStock);
        //入库单数量+已有库存量大于仓库预警容量
        if (inReceiptNumber.add(totalStock).compareTo(warningCapacity) > 0) {

        }
        //入库单数量+已有库存量大于仓库最大容量
        if (addNumber.compareTo(maxCapacity) > 0) {
            //2为仅提醒 3为禁止入库
            if (levelSign == 1) {
                if ("2".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    warnList.add(wmsBasicWarehouse.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,是否确认入库?");
                }
                if ("3".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    stopList.add(wmsBasicWarehouse.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,不可入库!");
                }
            }
            if (levelSign == 2) {
                if ("2".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    warnList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,是否确认入库?");
                }
                if ("3".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    stopList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,不可入库!");
                }
            }
            if (levelSign == 3) {
                if ("2".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    warnList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "-" + wmsBasicWarehouseAreaLocation.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,是否确认入库?");
                }
                if ("3".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    stopList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "-" + wmsBasicWarehouseAreaLocation.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,不可入库!");
                }
                //1宽度 2 个数
                if ("1".equals(wmsBasicWarehouse.getOtherCapacityControl())) {
                    //获取入库单总宽度(本次入库的宽度)
                    BigDecimal widthNumber = inReceiptMaterialList.stream().map(WmsInReceiptMaterial::getWidth).filter(ObjectUtil::isNotNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                    //总宽度不为0则校验
                    if (BigDecimal.ZERO.compareTo(widthNumber) != 0) {
                        //库位最大宽度为空不校验
                        if (ObjectUtil.isNotNull(wmsBasicWarehouseAreaLocation.getMaxWidth())) {
                            //sum(条料的宽度)
                            BigDecimal reduce = repertoryList.stream().map(WmsRepertory::getWidth).filter(ObjectUtil::isNotNull).reduce(BigDecimal.ZERO, BigDecimal::add);
                            long count = repertoryList.stream().filter(s -> StrUtil.isNotBlank(s.getBatchCode())).count();
                            //条料批次号数量* 条料间距
                            BigDecimal add = reduce.add(new BigDecimal(count).multiply(wmsBasicWarehouse.getToolLength()));
                            //【sum(条料的宽度)+条料批次号数量* 条料间距】+本次入库的宽度>【仓库信息】.【库位】.最大宽度()
                            if ((reduce.add(add).add(widthNumber).compareTo(wmsBasicWarehouseAreaLocation.getMaxWidth()) > 0)) {
                                stopList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "-" + wmsBasicWarehouseAreaLocation.getName() + "宽度" + wmsBasicWarehouseAreaLocation.getMaxWidth().stripTrailingZeros().toPlainString() + "本次入库后,宽度将超过最大宽度,不可入库!");
                            }
                        }
                    }
                }
            }
        }
        res.put("2", warnList);
        res.put("3", stopList);
        return res;
    }

    /**
     * 根据辅助单位校验(使用辅数量)
     */
    Map<String, List<String>> validByAssistantUnit(List<WmsInReceiptMaterial> inReceiptMaterialList, WmsBasicWarehouse wmsBasicWarehouse, WmsBasicWarehouseArea wmsBasicWarehouseArea, WmsBasicWarehouseAreaLocation wmsBasicWarehouseAreaLocation) {
        Map<String, List<String>> res = new HashMap<>();
        List<String> warnList = new ArrayList<>();
        List<String> stopList = new ArrayList<>();
        List<WmsRepertory> repertoryList = new ArrayList<>();
        //精确等级标识
        int levelSign = 0;
        //仓库最大容量 maxCapacity
        BigDecimal maxCapacity = BigDecimal.ZERO;
        //预警容量 warningCapacity
        BigDecimal warningCapacity = BigDecimal.ZERO;
        //只精确到仓库
        if (ObjectUtil.isNull(wmsBasicWarehouseArea) && ObjectUtil.isNull(wmsBasicWarehouseAreaLocation)) {
            //查询此仓库即时库存
            repertoryList = wmsRepertoryService.list(new LambdaQueryWrapper<WmsRepertory>()
                    .eq(WmsRepertory::getWmsBasicWarehouseId, wmsBasicWarehouse.getId())
            );
            maxCapacity = wmsBasicWarehouse.getMaxCapacityAssist();
            warningCapacity = wmsBasicWarehouse.getWarningCapacityAssist();
            levelSign = 1;
        }
        //只精确到库区
        if (ObjectUtil.isNotNull(wmsBasicWarehouseArea) && ObjectUtil.isNull(wmsBasicWarehouseAreaLocation)) {
            //查询此库区即时库存
            repertoryList = wmsRepertoryService.list(new LambdaQueryWrapper<WmsRepertory>()
                    .eq(WmsRepertory::getWmsBasicWarehouseId, wmsBasicWarehouse.getId())
                    .eq(WmsRepertory::getWmsBasicWarehouseAreaId, wmsBasicWarehouseArea.getId())
            );
            maxCapacity = wmsBasicWarehouseArea.getMaxCapacityAssist();
            warningCapacity = wmsBasicWarehouseArea.getWarningCapacityAssist();
            levelSign = 2;
        }
        //只精确到库位
        if (ObjectUtil.isNotNull(wmsBasicWarehouseArea) && ObjectUtil.isNotNull(wmsBasicWarehouseAreaLocation)) {
            //查询此库位即时库存
            repertoryList = wmsRepertoryService.list(new LambdaQueryWrapper<WmsRepertory>()
                    .eq(WmsRepertory::getWmsBasicWarehouseId, wmsBasicWarehouse.getId())
                    .eq(WmsRepertory::getWmsBasicWarehouseAreaId, wmsBasicWarehouseArea.getId())
                    .eq(WmsRepertory::getWmsBasicWarehouseAreaLocationId, wmsBasicWarehouseAreaLocation.getId())
            );
            maxCapacity = wmsBasicWarehouseAreaLocation.getMaxCapacityAssist();
            warningCapacity = wmsBasicWarehouseAreaLocation.getWarningCapacityAssist();
            levelSign = 3;
        }
        if (ObjectUtil.isNull(warningCapacity)) {
            warningCapacity = BigDecimal.ZERO;
        }
        if (ObjectUtil.isNull(maxCapacity)) {
            maxCapacity = BigDecimal.ZERO;
        }
        //入库单的数量
        BigDecimal inReceiptNumber = inReceiptMaterialList.stream().filter(s -> ObjectUtil.isNotNull(s.getAssistQuantity())).map(WmsInReceiptMaterial::getAssistQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
        //目前已有的即时库存(辅数量)
        BigDecimal totalStock = repertoryList.stream().filter(s -> ObjectUtil.isNotNull(s.getStockQuantitySub())).map(WmsRepertory::getStockQuantitySub).reduce(BigDecimal.ZERO, BigDecimal::add);
        //入库单的数量+目前已有的即时库存
        BigDecimal addNumber = inReceiptNumber.add(totalStock);
        //入库单数量+已有库存量大于仓库预警容量
        if (inReceiptNumber.add(totalStock).compareTo(warningCapacity) > 0) {

        }
        //入库单数量+已有库存量大于仓库最大容量
        if (addNumber.compareTo(maxCapacity) > 0) {
            //2为仅提醒 3为禁止入库
            if (levelSign == 1) {
                if ("2".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    warnList.add(wmsBasicWarehouse.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,是否确认入库?");
                }
                if ("3".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    stopList.add(wmsBasicWarehouse.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,不可入库!");
                }
            }
            if (levelSign == 2) {
                if ("2".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    warnList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,是否确认入库?");
                }
                if ("3".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    stopList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,不可入库!");
                }
            }
            if (levelSign == 3) {
                if ("2".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    warnList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "-" + wmsBasicWarehouseAreaLocation.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,是否确认入库?");
                }
                if ("3".equals(wmsBasicWarehouse.getOverCapacityWay())) {
                    stopList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "-" + wmsBasicWarehouseAreaLocation.getName() + "库存数量" + totalStock.stripTrailingZeros().toPlainString() + "本次入库后仓库数量" + addNumber.stripTrailingZeros().toPlainString() + "将超过最大容量,不可入库!");
                }
                //1宽度 2 个数
                if ("1".equals(wmsBasicWarehouse.getOtherCapacityControl())) {
                    //获取入库单总宽度(本次入库的宽度)
                    BigDecimal widthNumber = inReceiptMaterialList.stream().filter(s -> ObjectUtil.isNotNull(s.getWidth())).map(WmsInReceiptMaterial::getWidth).reduce(BigDecimal.ZERO, BigDecimal::add);
                    //总宽度不为0则校验
                    if (BigDecimal.ZERO.compareTo(widthNumber) != 0) {
                        //sum(条料的宽度)
                        BigDecimal reduce = repertoryList.stream().filter(s -> ObjectUtil.isNotNull(s.getWidth())).map(WmsRepertory::getWidth).reduce(BigDecimal.ZERO, BigDecimal::add);
                        long count = repertoryList.stream().filter(s -> StrUtil.isNotBlank(s.getBatchCode())).count();
                        //条料批次号数量* 条料间距
                        BigDecimal add = reduce.add(new BigDecimal(count).multiply(wmsBasicWarehouse.getToolLength()));
                        //【sum(条料的宽度)+条料批次号数量* 条料间距】+本次入库的宽度>【仓库信息】.【库位】.最大宽度()
                        if ((reduce.add(add).add(widthNumber).compareTo(wmsBasicWarehouseAreaLocation.getMaxWidth()) > 0)) {
                            stopList.add(wmsBasicWarehouse.getName() + "-" + wmsBasicWarehouseArea.getName() + "-" + wmsBasicWarehouseAreaLocation.getName() + "宽度" + wmsBasicWarehouseAreaLocation.getMaxWidth().stripTrailingZeros().toPlainString() + "本次入库后,宽度将超过最大宽度,不可入库!");
                        }
                    }
                }
            }
        }
        res.put("2", warnList);
        res.put("3", stopList);
        return res;
    }

    /**
     * 校验入库单物料是否满足仓库物料分类要求
     *
     * @Param 入库单id
     */
    public List<String> validMaterialTypeByHouse(List<WmsInReceiptMaterial> materials) {
        List<String> list = new ArrayList<>();
        List<String> wareHouseIdList = materials.stream().filter(s -> ObjectUtil.isNotNull(s.getWmsBasicWarehouseId())).map(WmsInReceiptMaterial::getWmsBasicWarehouseId).distinct().collect(Collectors.toList());
        List<WmsBasicWarehouse> warehouses = wmsBasicWarehouseMapper.selectList(new LambdaQueryWrapper<WmsBasicWarehouse>()
                .in(CollectionUtil.isNotEmpty(wareHouseIdList), WmsBasicWarehouse::getId, wareHouseIdList)
        );
        //仓库id-仓库下的物料分类map
        Map<String, String> houseMap = warehouses.stream().filter(s -> StrUtil.isNotBlank(s.getMaterialTypeId())).collect(Collectors.toMap(WmsBasicWarehouse::getId, WmsBasicWarehouse::getMaterialTypeId));
        //仓库id-仓库名称map
        Map<String, String> houseNameMap = warehouses.stream().filter(s -> StrUtil.isNotBlank(s.getName())).collect(Collectors.toMap(WmsBasicWarehouse::getId, WmsBasicWarehouse::getName));
        List<String> materialIdList = materials.stream().map(WmsInReceiptMaterial::getWmsBasicMaterialId).collect(Collectors.toList());
        List<BasicMaterial> basicMaterials = basicMaterialMapper.selectList(new LambdaQueryWrapper<BasicMaterial>()
                .in(CollectionUtil.isNotEmpty(materialIdList), BasicMaterial::getId, materialIdList)
        );
        //物料id-物料分类map
        Map<String, String> materialMap = basicMaterials.stream().filter(s -> StrUtil.isNotBlank(s.getMaterialTypeId())).collect(Collectors.toMap(BasicMaterial::getId, BasicMaterial::getMaterialTypeId));
        //物料id-物料名称分类
        Map<String, String> materialNameMap = basicMaterials.stream().filter(s -> StrUtil.isNotBlank(s.getName())).collect(Collectors.toMap(BasicMaterial::getId, BasicMaterial::getName));
        materials.forEach(one -> {
            String houseMaterialType = houseMap.get(one.getWmsBasicWarehouseId());
            String materialType = materialMap.get(one.getWmsBasicMaterialId());
            if (StrUtil.isNotBlank(houseMaterialType)) {
                if (StrUtil.isNotBlank(materialType)) {
                    if (!houseMaterialType.contains(materialType)) {
                        list.add("仓库:" + houseNameMap.get(one.getWmsBasicWarehouseId()) + "的物料分类不包含物料:" + materialNameMap.get(one.getWmsBasicMaterialId()));
                    }
                }
            }

        });
        return list;
    }

    /**
     * 校验入库单物料是否完全相同
     *
     * @Param 入库单id
     */
    List<String> validMaterial(String id) {
        List<String> res = new ArrayList<>();
        List<WmsInReceiptMaterial> materials = wmsInReceiptMaterialService.list(new LambdaQueryWrapper<WmsInReceiptMaterial>()
                .eq(WmsInReceiptMaterial::getWmsInReceiptId, id)
        );
        if (CollectionUtil.isNotEmpty(materials)) {
            Map<String, List<WmsInReceiptMaterial>> collect = materials.stream().collect(Collectors.groupingBy(
                    s -> s.getWmsBasicMaterialId() + "-"
                            + s.getBatchCode() + "-"
                            + s.getWmsBasicWarehouseId() + "-"
                            + s.getWmsBasicWarehouseAreaId() + "-"
                            + s.getWmsBasicWarehouseAreaLocationId() + "-"
                            + s.getOriginalSystemLineNumber()
            ));
            collect.keySet().forEach(key -> {
                if (collect.get(key).size() > 1) {
                    res.add("不可选取相同参数的物料");
                }
            });
        }
        return res;
    }

    /**
     * 校验单据配置是否可分批出入库: 1.任务有多个物料,单据的物料数小于任务 2.单据的物料数等于任务的物料数,但是数量小于对应任务的数量
     *
     * @Param 入库单id
     */
    List<String> validPrintConfig(WmsInReceipt wmsInReceipt,List<WmsInReceiptMaterial> inReceiptMaterials) {
        List<String> list = new ArrayList<>();
        PrintConfig config = iPrintConfigService.getOne(new LambdaQueryWrapper<PrintConfig>()
                .eq(PrintConfig::getBusinessType, "document_task")
                .eq(PrintConfig::getDocumentType, wmsInReceipt.getDocumentType())
                .last("limit 1")
        );
        if (ObjectUtil.isNotNull(config)) {
            if (config.getTaskCanExecuteBatches() != null) {
                if (config.getTaskCanExecuteBatches() == 0) {
                    //1.任务有多个物料,单据的物料数小于任务
                    List<WmsInReceiptTaskMaterial> taskMaterials = iWmsInReceiptTaskMaterialService.list(new LambdaQueryWrapper<WmsInReceiptTaskMaterial>()
                            .eq(WmsInReceiptTaskMaterial::getWmsInReceiptTaskId, wmsInReceipt.getWmsInReceiptTaskId())
                    );
                    if (CollectionUtil.isNotEmpty(taskMaterials) && CollectionUtil.isNotEmpty(inReceiptMaterials)) {
                        //1.单据的物料数小于任务,找出少了任务的哪几种物料
                        //2.单据的物料数等于任务的物料数,但是数量小于对应任务的数量
                        List<WmsInReceiptTaskMaterial> taskMaterialList = new ArrayList<>(taskMaterials);
                        for (WmsInReceiptTaskMaterial taskMaterial : taskMaterials) {
                            for (WmsInReceiptMaterial inReceiptMaterial : inReceiptMaterials) {
                                if (!taskMaterial.getWmsBasicMaterialId().equals(inReceiptMaterial.getWmsBasicMaterialId())) {
                                    continue;
                                }
                                if (StrUtil.isNotBlank(taskMaterial.getBatchCode())) {
                                    if (StrUtil.isBlank(inReceiptMaterial.getBatchCode())) {
                                        continue;
                                    }
                                    if (!taskMaterial.getBatchCode().equals(inReceiptMaterial.getBatchCode())) {
                                        continue;
                                    }
                                }
                                if (taskMaterial.getPlanQuantity() != null && inReceiptMaterial.getWarehouseQuantity() != null) {
                                    if (inReceiptMaterial.getWarehouseQuantity().compareTo(taskMaterial.getPlanQuantity()) < 0) {
                                        String materialCode = "";
                                        String batchCode = "";
                                        BasicMaterial basicMaterial = basicMaterialMapper.selectById(taskMaterial.getWmsBasicMaterialId());
                                        if (basicMaterial != null) {
                                            materialCode = "物料编码" + basicMaterial.getCode();
                                        }
                                        if (StrUtil.isNotBlank(taskMaterial.getBatchCode())) {
                                            batchCode = "批次号" + taskMaterial.getBatchCode();
                                        }
                                        list.add("入库任务中的" + materialCode + batchCode + "尚未入库,提交后,任务将强制完成,不可继续执行,是否确定提交?");
                                    }
                                }
                                taskMaterialList.remove(taskMaterial);
                            }
                        }
                        for (WmsInReceiptTaskMaterial taskMaterial : taskMaterialList) {
                            String materialCode = "";
                            String batchCode = "";
                            BasicMaterial basicMaterial = basicMaterialMapper.selectById(taskMaterial.getWmsBasicMaterialId());
                            if (basicMaterial != null) {
                                materialCode = "物料编码" + basicMaterial.getCode();
                            }
                            if (StrUtil.isNotBlank(taskMaterial.getBatchCode())) {
                                batchCode = "批次号" + taskMaterial.getBatchCode();
                            }
                            list.add("入库任务中的" + materialCode + batchCode + "尚未入库,提交后,任务将强制完成,不可继续执行,是否确定提交?");
                        }
                    }
                }
            }
        }
        return list;
    }

    /**
     * 校验是否超额入库
     *
     * @Param 入库单id
     */
    boolean validBeyondInNumber(WmsInReceipt wmsInReceipt,List<WmsInReceiptMaterial> list) {
        for (WmsInReceiptMaterial one : list) {
            LambdaQueryWrapper<WmsInReceiptTaskMaterial> queryWrapper = new LambdaQueryWrapper<>();
            if (StrUtil.isNotBlank(one.getBatchCode())) {
                queryWrapper.eq(WmsInReceiptTaskMaterial::getBatchCode, one.getBatchCode());
            }
            queryWrapper.eq(WmsInReceiptTaskMaterial::getWmsBasicMaterialId, one.getWmsBasicMaterialId());
            queryWrapper.eq(WmsInReceiptTaskMaterial::getWmsInReceiptTaskId, wmsInReceipt.getWmsInReceiptTaskId());
            queryWrapper.last("limit 1");
            WmsInReceiptTaskMaterial taskMaterial = iWmsInReceiptTaskMaterialService.getOne(queryWrapper);
            if (ObjectUtil.isNotNull(taskMaterial)) {
                if (ObjectUtil.isNotNull(taskMaterial.getPlanQuantity()) && ObjectUtil.isNotNull(one.getWarehouseQuantity())) {
                    BigDecimal hasWarehouse = BigDecimal.ZERO;
                    if (ObjectUtil.isNotNull(taskMaterial.getWarehousedQuantity())){
                        hasWarehouse = taskMaterial.getWarehousedQuantity();
                    }
                    if (hasWarehouse.add(taskMaterial.getPlanQuantity()).compareTo(one.getWarehouseQuantity()) < 0) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    /**
     * 校验仓库是否有不存在的情况(该校验针对于SAP发送工厂加库位,wms未查到,存储的是工厂加库位的字符串拼接,该情况禁止入库)
     * 如果仓库未空也禁止入库
     * @Param 入库单id
     */
    void validWarehouseIdExsit(List<WmsInReceiptMaterial> list){
        List<WmsBasicWarehouse> wmsBasicWarehouses = wmsBasicWarehouseMapper.selectList(new LambdaQueryWrapper<>());
        List<String> basicWarehouseIdList = wmsBasicWarehouses.stream().map(WmsBasicWarehouse::getId).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(list)){
            List<String> collect = list.stream().map(WmsInReceiptMaterial::getWmsBasicWarehouseId).filter(StrUtil::isNotBlank).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(collect)){
                if (collect.size()<list.size()){
                    throw new JeecgBootException("该单据明细存在仓库为空的情况,请核查!");
                }
                if (!basicWarehouseIdList.containsAll(collect)){
                    throw new JeecgBootException("该单据明细存在仓库在WMS系统中不存在的情况,请核查!");
                }
            }
        }
    }
    /**
     * 校验物料检验
     */
    void validInspect(WmsInReceipt wmsInReceipt,List<WmsInReceiptMaterial> wmsInReceiptMaterialList){
        if (wmsInReceiptMaterialList != null && wmsInReceiptMaterialList.size() > 0) {
            for (WmsInReceiptMaterial inReceiptMaterial : wmsInReceiptMaterialList) {
                LambdaQueryWrapper<WmsInReceiptTaskMaterial> queryWrapper = new LambdaQueryWrapper<WmsInReceiptTaskMaterial>()
                        .eq(WmsInReceiptTaskMaterial::getWmsInReceiptTaskId, wmsInReceipt.getWmsInReceiptTaskId());
                if (StrUtil.isNotBlank(inReceiptMaterial.getBatchCode())){
                    queryWrapper.eq(WmsInReceiptTaskMaterial::getBatchCode, inReceiptMaterial.getBatchCode());
                }
                if (StrUtil.isNotBlank(inReceiptMaterial.getWmsBasicMaterialId())){
                    queryWrapper.eq(WmsInReceiptTaskMaterial::getWmsBasicMaterialId,inReceiptMaterial.getWmsBasicMaterialId());
                }
                queryWrapper.last("limit 1");
                WmsInReceiptTaskMaterial inReceiptTaskMaterial = iWmsInReceiptTaskMaterialService.getOne(queryWrapper);

                if (inReceiptTaskMaterial == null){
                    log.error("入库任务物料明细中未找到对应记录，任务id{},批次号：{}，物料id：{}",wmsInReceipt.getWmsInReceiptTaskId(),
                            inReceiptMaterial.getBatchCode(),inReceiptMaterial.getWmsBasicMaterialId());
                    continue;
                }
                inReceiptMaterial.setWmsInReceiptTaskMaterialId(inReceiptTaskMaterial.getId());
                if ("true".equals(inReceiptTaskMaterial.getIncomingQuality())
                        && "false".equals(inReceiptTaskMaterial.getUnInspectCanPut())
                        && (!InspectStatusEnum.INSPECTED.getName().equals(inReceiptTaskMaterial.getInspectStatus())
                        || InspectResultEnum.NO_PASS.getName().equals(inReceiptTaskMaterial.getInspectResult()))){
                    BasicMaterial byId = basicMaterialMapper.selectById(inReceiptMaterial.getWmsBasicMaterialId());
                    throw new JeecgBootException(inReceiptTaskMaterial.getBatchCode()+"批次号，"+byId.getName()+
                            "物料必须检验合格后才能入库");
                }
            }
        }
    }
    /**
     * 入库时候，需要校验，物料必须入到仓库的最小单位
     */
    void validLocation(List<WmsInReceiptMaterial> wmsInReceiptMaterialList){
        for (WmsInReceiptMaterial inReceiptMaterial : wmsInReceiptMaterialList) {
            if (StrUtil.isBlank(inReceiptMaterial.getWmsBasicWarehouseId())){
                throw new JeecgBootException("该单据明细存在仓库为空的情况,请核查!");
            }
            if (StrUtil.isNotBlank(inReceiptMaterial.getWmsBasicWarehouseId()) && StrUtil.isBlank(inReceiptMaterial.getWmsBasicWarehouseAreaId())){
                long count = wmsBasicWarehouseAreaService.count(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                        .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, inReceiptMaterial.getWmsBasicWarehouseId())
                );
                if (count>0){
                    throw new JeecgBootException("该单据明细存在仓库下有库区,但是库区为空的情况,请核查!");
                }
            }
            if (StrUtil.isNotBlank(inReceiptMaterial.getWmsBasicWarehouseAreaId()) && StrUtil.isBlank(inReceiptMaterial.getWmsBasicWarehouseAreaLocationId())){
                long count = wmsBasicWarehouseAreaLocationService.count(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                        .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, inReceiptMaterial.getWmsBasicWarehouseAreaId())
                );
                if (count>0){
                    throw new JeecgBootException("该单据明细存在库区下有库位,但是库位为空的情况,请核查!");
                }
            }
        }
    }
    /**
     * 逻辑:一个任务已经存在提交后入库单，又重新提交入库单时，需要去校验之前入库单的物料信息是否和本次提交的入库单物料信息存在冲突，
     * 如果有冲突要提示报错，没有则正常入库；在正常入库时又发现库存存在同批次同物料号的物料，按逻辑2的库存校验走。
     * 逻辑2:一个任务的第一个入库单在入库时，校验库存中是否有同物料编码同批次号的物料，
     * 如果有，不报错，更新此物料的仓库信息、最新入库时间和更新人更新时间；
     *
     */
    void validSubmit(WmsInReceipt wmsInReceipt,List<WmsInReceiptMaterial> materialList){
        Map<String, String> materialType = getMaterialType(materialList);
        //查询任务是否存在已提交的入库单
        List<WmsInReceipt> list = wmsInReceiptMapper.selectList(new LambdaQueryWrapper<WmsInReceipt>()
                .eq(WmsInReceipt::getWmsInReceiptTaskId, wmsInReceipt.getWmsInReceiptTaskId())
                .ne(WmsInReceipt::getId, wmsInReceipt.getId())
                .eq(WmsInReceipt::getDocumentStatus, DocumentStatusEnum.COMPLETE.getCode())
        );
        if (CollectionUtil.isNotEmpty(list)){
            List<String> collect = list.stream().map(WmsInReceipt::getId).collect(Collectors.toList());
            List<WmsInReceiptMaterial> materials = wmsInReceiptMaterialService.list(new LambdaQueryWrapper<WmsInReceiptMaterial>()
                    .in(WmsInReceiptMaterial::getWmsInReceiptId, collect)
            );
            materials = materials.stream().filter(s->Objects.equals(materialType.get(s.getWmsBasicMaterialId()),"3")).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(materials)){
                materials.forEach(one->{
                    if (one.getBatchCode() == null){
                        one.setBatchCode("");
                    }
                });
                //物料id-名称map
                Map<String,String> map = new HashMap<>();
                List<String> materialIds = materials.stream().map(WmsInReceiptMaterial::getWmsBasicMaterialId).distinct().collect(Collectors.toList());
                map = basicMaterialService.list(new LambdaQueryWrapper<BasicMaterial>()
                        .in(BasicMaterial::getId,materialIds)
                ).stream().collect(Collectors.toMap(BasicMaterial::getId, BasicMaterial::getName));
                for (WmsInReceiptMaterial material : materials) {
                    for (WmsInReceiptMaterial inReceiptMaterial : materialList) {
                        if (Objects.equals(material.getBatchCode(),inReceiptMaterial.getBatchCode()) && Objects.equals(material.getWmsBasicMaterialId(),inReceiptMaterial.getWmsBasicMaterialId())){
                            String msg = "";
                            if (StrUtil.isNotBlank(inReceiptMaterial.getBatchCode())){
                                msg = "批次: "+inReceiptMaterial.getBatchCode()+",";
                            }
                            msg = msg + "物料: "+map.get(inReceiptMaterial.getWmsBasicMaterialId());
                            msg = msg + "已经提交过!";
                            throw new JeecgBootException(msg);
                        }
                    }
                }
            }
        }
    }
    //物料id-物料控制方式map
    Map<String, String> getMaterialType(List<WmsInReceiptMaterial> materialList){
        Map<String, String> map = new HashMap<>();
        List<String> collect = materialList.stream().map(WmsInReceiptMaterial::getWmsBasicMaterialId).distinct().collect(Collectors.toList());
        List<MaterialInfoVO> materialInfoList = wmsValidMapper.selectInboundControlType(collect);
        map = materialInfoList.stream().filter(s->ObjectUtil.isNotNull(s.getInboundControlType())).collect(Collectors.toMap(MaterialInfoVO::getWmsBasicMaterialId, MaterialInfoVO::getInboundControlType));
        return map;
    }
}


